package com.neusoft.javafeatures9.juc;

import java.lang.invoke.SerializedLambda;
import java.util.Arrays;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

public class ExecutorExample {

    public static void main(String[] args) throws InterruptedException {

        System.out.println(Runtime.getRuntime().availableProcessors());

        //创建一个最大吞吐量的线程池
        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //提交一个任务到线程池中
        executorService.submit(() -> {
            System.out.println("Hello World!");
        });
        executorService.awaitTermination(1, TimeUnit.SECONDS);
        executorService.shutdown();


        Executors.newCachedThreadPool();
        Executors.newFixedThreadPool(1);
        Executors.newSingleThreadExecutor();
        Executors.newScheduledThreadPool(1);

        testCompletableFuture2();
    }

    private static void testCompletableFuture1() throws InterruptedException {
        CompletableFuture<String> future = new CompletableFuture<>();
        // 下面利用多线程的概念模拟一个炮兵打跑的形式，因为所有的操作都需要有统一的口令
        for (int x = 0; x < 200; x++) {
            new Thread(()->{
                System.out.printf("【START】%s，炮兵就位，等待开炮命令发出。%n", Thread.currentThread().getName());
                System.out.println("【START】%s 当前时间" + System.nanoTime());
                try { // get()方法未收到数据则持续阻塞，收到数据则解除阻塞
                    System.err.printf("〖END〗%s，解除阻塞，收到执行命令：%s%n", Thread.currentThread().getName(), future.get());
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }, "炮兵 - " + x).start();
        }
        TimeUnit.SECONDS.sleep(15); // 准备的模拟延迟
        System.out.println("【Main-】%s 当前时间" + System.nanoTime());
        future.complete("开炮");
    }

    private static void testCompletableFuture2() throws InterruptedException {
        CompletableFuture<Void> future = CompletableFuture.runAsync(()->{
            System.err.println("【*** 异步线程 ***】突然接到了上将军的紧急联系电话。");
            try {
                TimeUnit.SECONDS.sleep(15);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } // 当此异步线程执行完成之后，才会让所有的子线程恢复执行
            System.err.println("【*** 异步线程 ***】接到了新的作战任务，更改炮兵的作战目标。");
        }); // 异步线程不用考虑返回值了
        // 下面利用多线程的概念模拟一个炮兵打跑的形式，因为所有的操作都需要有统一的口令
        for (int x = 0; x < 20; x++) {
            new Thread(()->{
                System.out.printf("【START】%s，炮兵就位，等待开炮命令发出。%n", Thread.currentThread().getName());
                try { // get()方法未收到数据则持续阻塞，收到数据则解除阻塞
                    future.get(); // 异步的操作是没有返回结果的
                    System.err.printf("〖END〗%s，收到开火命令，万炮齐鸣。%n", Thread.currentThread().getName());
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }, "炮兵 - " + x).start();
        }
        System.out.println("【★主线程★】所有的炮兵线程进入到了就绪状态，等待后续命令的发送。");
    }
}
